import {createContext, useContext, useMemo, useState} from "react";
import {AppProviderMethod} from "./AppProviderMethod.ts";
import {createTheme, PaletteMode, useMediaQuery} from "@mui/material";
import {Util} from "./Util.ts";

// 全局程序上下文用户数据接口
interface info {
    [key: string]: unknown;
}

// 全局程序上下文默认方法接口
interface AppHandle {
    // 标题
    title: string,
    // 设置标题
    setTitle: (title: string) => string,
    // 用户信息
    info: info | null,
    // 设置用户信息
    setUserInfo: (info: info | null) => void,
    // 正则表达式
    Regex: { account: RegExp, email: RegExp }
}

// 全局程序上下文
const AppContext = createContext<AppHandle | undefined>(undefined);

// 返回全局程序上下文
const useAppContext = () => {
    return useContext(AppContext);
}

// 程序上下文提供器
const AppContextProvider = () => {
    // 站点标题
    const [title, _setTitle] = useState("");

    // 设置标题
    const setTitle = (title: string) => {
        document.title = title;
        _setTitle(title);
        return title;
    }

    // 读取已登陆的会话信息
    const session = Util.Storage.getSession("SESSION-USER");

    // 设置已登陆会话信息（判断本地会话是否存在）
    const [info, setUserInfo] = useState<info | null>(session ? session : null);

    // 正则表达
    const Regex = useMemo(() => ({
        account: /^[a-zA-Z0-9_]{4,30}$/,
        email: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(?:\.[a-zA-Z]{2,}){0,2}$/,
    }), []);

    // 应用提供函数
    const AppMethod = useMemo(() => (AppProviderMethod.AppMethod({
        title, setTitle, info, setUserInfo, Regex
    })), [Regex, info, title]);

    // 返回对象
    return {AppMethod};
}

// 全局主题上下文接口
interface ThemeHandle {
    // 模式查询
    mode: number,
    // 设置模式
    setThemeMode: (
        // 登陆状态
        state: boolean,
        // 模式数字
        mode: number,
    ) => void
}

// 全局主题上下文
const AppThemeContext = createContext<ThemeHandle | undefined>(undefined);

// 返回主题上下文
const useAppThemeContext = () => {
    return useContext(AppThemeContext);
}

// 主题上下文提供器
const AppThemeContextProvider = () => {
    // 查询系统主题模式
    const SystemMode: PaletteMode = useMediaQuery('(prefers-color-scheme: light)') ? "light" : "dark";

    // 如果不存在本地数据，则存储主题模式 - 0 跟随系统 1 浅色模式 2 深色模式
    // if (!window.localStorage.getItem("THEME-MODE")) window.localStorage.setItem("THEME-MODE", "0");
    if (!Util.Storage.getLocal("THEME-MODE")) Util.Storage.setLocal("THEME-MODE", "0");

    // 读取本地主题数据
    // let localMode = parseInt(window.localStorage.getItem("THEME-MODE") || "", 10);
    let localMode = parseInt(Util.Storage.getLocal("THEME-MODE"), 10);
    // 判断是否为空，设定值
    localMode = isNaN(localMode) ? 0 : localMode;

    // 读取已登录的会话信息 SI = SessionInfo
    const SI = Util.Storage.getSession("SESSION-USER");

    // 转换已登录的会话信息
    const [SessionMode, setSessionMode] = useState(SI !== null && SI['theme'] !== null ? SI['theme'] : null);

    // 转换主题模式数字类型，供查询用
    const [mode, setModeNumber] = useState<number>(SessionMode ? SessionMode : localMode);

    // 设置是否允许切换主题模式---登录模式
    // SSM = SessionSwitchMode
    // setSSM = setSessionSwitchMode
    const [SSM, setSSM] = useState<boolean>(SessionMode !== 0);

    // 设置转换规则后的模式---登录模式 0 是跟随系统，默认light（反正不会用这个），1 则是浅色模式，2 则是深色模式
    // SMS = SessionModeString
    // setSMS = setSessionModeString
    const [SMS, setSMS] = useState<PaletteMode>(SessionMode === 0 || SessionMode === 1 ? "light" : "dark");

    // 设置是否允许切换主题模式---本地模式
    // LSM = LocalSwitchMode
    // setLSM = setLocalSwitchMode
    const [LSM, setLSM] = useState<boolean>(localMode !== 0);

    // 设置转换规则后的模式---本地模式 0 是跟随系统，默认light（反正不会用这个），1 则是浅色模式，2 则是深色模式
    // LMS = LocalModeString
    // setLMS = setLocalModeString
    const [LMS, setLMS] = useState<PaletteMode>(localMode === 0 || localMode === 1 ? "light" : "dark");

    // 设置封装切换主题函数
    const setThemeMode = (state: boolean, mode: number) => {
        // 更新本地存储模式信息
        if (!state) Util.Storage.setLocal("THEME-MODE", String(mode));
        // 更新查询模式数字
        setModeNumber(mode);
        // 已登陆
        if (state) {
            // 设置登陆主题模式
            setSessionMode(mode);
            // 更新允许切换模式状态
            setSSM(mode !== 0);
            // 应用主题模式
            setSMS(mode !== 2 ? "light" : "dark");
        } else {
            // 设置登陆主题模式
            setSessionMode(null);
            // 更新允许切换模式状态
            setLSM(mode !== 0);
            // 应用主题模式
            setLMS(mode !== 2 ? "light" : "dark");
        }
    }

    // 应用及检测主题改动
    const ChangeThemeStyle = useMemo(() => createTheme({
        palette: {mode: SessionMode !== null ? (SSM ? SMS : SystemMode) : (LSM ? LMS : SystemMode)},
    }), [LMS, LSM, SMS, SSM, SessionMode, SystemMode]);

    // 全局上下文提供函数
    const ThemeMethod = useMemo(() => (AppProviderMethod.ThemeMethod({
        mode, setThemeMode
    })), [mode]);

    // 返回相关对象
    return {ChangeThemeStyle, ThemeMethod};
}


const AppProvider = {
    AppThemeContext,
    useAppThemeContext,
    AppThemeContextProvider,
    AppContext,
    useAppContext,
    AppContextProvider
}
export default AppProvider;